package game;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class GameHistory
{
	public GameHistory(String name)
	{
		gameName = name;
		itsGameResults = new LinkedList<GameResults>();
	}
	
	public void load()
	{
		String filename = new String(gameName + "history");
		File file = new File(filename);
		
		if(file.exists() == false)
		{
			try
			{
				file.createNewFile();
			}
			catch(IOException ioe)
			{
		       System.out.println("Error while creating a new empty file :" + ioe);
			}
		}
		file = null;
		
		try
		{
			FileInputStream fstream = new FileInputStream(filename);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String line;
			
			while ((line = br.readLine()) != null)
			{
				parseLine(line);
			}
			
			in.close();
		}
		catch(Exception e)
		{
			System.err.println("Error: " + e.getMessage());
		}
	}
	
	private void parseLine(String line)
	{
		String [] tokens = line.split("\\s");
		if(tokens.length != 3)
		{
			System.out.println("Illegal format in history file " + gameName + "history");
			return;
		}
		
		try
		{
			int numPlayers = Integer.parseInt(tokens[0]);
			int movesPlayed = Integer.parseInt(tokens[1]);
			int winner = Integer.parseInt(tokens[2]);
			addGameResults(new GameResults(numPlayers, movesPlayed, winner));
		}
		catch(NumberFormatException e)
		{
			System.out.println("Illegal format in history file "  + gameName + "history " + e.toString());
		}
	}
	
	public void save()
	{
		String filename = new String(gameName + "history");
		File file = new File(filename);
		if(file.exists())
		{
			file.delete();
		}
		
		file = new File(filename);
		try
		{
			file.createNewFile();
		}
		catch(IOException ioe)
		{
	       System.out.println("Error while creating a new empty file :" + ioe);
	       return;
		}
		
		FileWriter fstream = null;
		try
		{
			fstream = new FileWriter(filename);
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
		BufferedWriter out = new BufferedWriter(fstream);
		try
		{
			Iterator<GameResults> resultsIter = itsGameResults.iterator();
			while(resultsIter.hasNext())
			{
				GameResults results = resultsIter.next();
				out.write(results.getNumPlayers() + " " + results.getMovesPlayed() + " " + results.getWinner());
				out.newLine();
			}
			out.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		
		
		
	}
	
	public void addGameResults(GameResults result)
	{
		itsGameResults.add(result);
	}

	public void display()
	{
		int topWinner = getTopWinner();
		int numWinnings = getNumGamesWon(topWinner);
		
		System.out.println("Game " + gameName + " has been played " + itsGameResults.size() + " times");
		if(topWinner > 0)
		{
			System.out.println("Player " + topWinner + " has won most of the games (" + numWinnings + " games)!");
		}
		else
		{
			System.out.println("No player has won any game up to now");
		}
	}
	
	private int getTopWinner()
	{
		// create a distribution of winners, implemented by a map where
		// a key is the player id, and the value is how many times did
		// that player win
		Map<Integer, Integer> distributionChart = new HashMap<Integer, Integer>();
		Iterator<GameResults> resultsIter = itsGameResults.iterator();
		while(resultsIter.hasNext())
		{
			GameResults results = resultsIter.next();
			Integer winnerId = new Integer(results.getWinner());
			if(winnerId == 0)
			{
				// ignore results of draws or games that were stopped
				continue;
			}
			
			if(distributionChart.containsKey(winnerId))
			{
				int wins = distributionChart.get(winnerId);
				wins++;
				distributionChart.put(winnerId, new Integer(wins));
			}
			else
			{
				distributionChart.put(winnerId, new Integer(1));
			}
		}
		
		// get the winner with maximum wins from the distribution chart
		Iterator chartIter = distributionChart.entrySet().iterator();
		int playerId = 0;
		int numWins = 0;
		while(chartIter.hasNext())
		{
			Map.Entry pair = (Map.Entry)chartIter.next();
			Integer value = (Integer)pair.getValue();
			Integer key = (Integer)pair.getKey();
			
			if(value.intValue() > numWins)
			{
				numWins = value.intValue();
				playerId = key.intValue();
			}
		}
		return playerId;
	}
	
	private int getNumGamesWon(int player)
	{
		if(player == 0)
		{
			return 0;
		}
		int numWins = 0;
		
		Iterator<GameResults> resultsIter = itsGameResults.iterator();
		while(resultsIter.hasNext())
		{
			GameResults results = resultsIter.next();
			Integer winnerId = new Integer(results.getWinner());
			if(winnerId.intValue() == player)
			{
				numWins++;
			}
		}
		return numWins;
	}
	
	private List<GameResults> itsGameResults;
	private String gameName;
}
